﻿using Furion.EventBus;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Furion.Application
{


    /// <summary>
    /// 政策
    /// </summary>
    [AppAuthorize, ApiDescriptionSettings("Business", Name = "Policy", Order = 2, Tag = "政策")]
    public class PolicyService : IDynamicApiController
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IRepository<Policy> _policyRepository;
        private readonly IAuthorizationManager _authorizationManager;

        private readonly IEventPublisher _eventPublisher;



        public PolicyService(IHttpContextAccessor httpContextAccessor,
            IRepository<Policy> policyRepository,
            IEventPublisher eventPublisher,
            IAuthorizationManager authorizationManager)
        {
            _httpContextAccessor = httpContextAccessor;
            _policyRepository = policyRepository;
            _authorizationManager = authorizationManager;

            _eventPublisher = eventPublisher;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous, HttpGet("/Policy/Test"), ApiDescriptionSettings(Name = "Test")]
        public string Test()
        {
            return $"{Assembly.GetExecutingAssembly().FullName};IP:{HttpContextExtensions.GetRemoteIpAddressToIPv4(_httpContextAccessor.HttpContext)};当前时间：{DateTime.Now:G};Port：{App.Configuration["ConsulRegisterOptions:Port"]}";
        }


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_Add), HttpPost("/Policy/Add"), ApiDescriptionSettings(Name = "Add")]
        public async Task<string> AddAsync([Required] PolicyAddInput input)
        {
            var addInput = input.Adapt<Policy>();
            addInput.CreatedTime = DateTime.Now;
            addInput.UpdatedTime = DateTime.Now;
            addInput.CreatedUserId = _authorizationManager.UserId;
            addInput.CreatedUserName = _authorizationManager.Name;
            addInput.UpdatedUserId = 0;
            addInput.UpdatedUserName = "";
            addInput.Id = Yitter.IdGenerator.YitIdHelper.NextId();

            //var entryEntity = await _policyRepository.InsertNowAsync(addInput);
            //return $"主键：{entryEntity.Entity.Id};IP:{HttpContextExtensions.GetRemoteIpAddressToIPv4(_httpContextAccessor.HttpContext)};当前时间：{DateTime.Now:G};Port：{App.Configuration["ConsulRegisterOptions:Port"]}";

            await _eventPublisher.PublishAsync("ToDo:Create", addInput.ToJson());
            return $"主键：{addInput.Id};IP:{HttpContextExtensions.GetRemoteIpAddressToIPv4(_httpContextAccessor.HttpContext)};当前时间：{DateTime.Now:G};Port：{App.Configuration["ConsulRegisterOptions:Port"]}";
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_Edit), HttpPost("/Policy/Edit"), ApiDescriptionSettings(Name = "Edit")]
        public async Task EditAsync([Required] PolicyEditInput input)
        {
            var editInput = input.Adapt<Policy>();

            editInput.UpdatedTime = DateTime.Now;
            editInput.CreatedUserId = _authorizationManager.UserId;            
            editInput.UpdatedUserId = _authorizationManager.UserId;
            editInput.UpdatedUserName = "";
            //await _policyRepository.UpdateExcludeNowAsync(editInput, new[] { nameof(Policy.CreatedUserId), nameof(Policy.CreatedUserName), nameof(Policy.CreatedTime), nameof(Policy.IsDeleted) });

            await _eventPublisher.PublishAsync("ToDo:Update", editInput.ToJson());
        }


        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_List), HttpGet("/Policy/PageList"), ApiDescriptionSettings(Name = "PageList")]
        public async Task<PagedList<PolicyItem>> PageListAsync([FromQuery] PolicyPageInput input)
        {
            var hasKeyword = !string.IsNullOrEmpty(input.Keyword?.Trim());

            var list = await _policyRepository
                 .Where(a => a.IsDeleted == input.IsDeleted)
                .Where(input.Statu > -1, a => a.Statu == input.Statu)
                .Where(hasKeyword, a => a.Title.Contains(input.Keyword.Trim()) || a.Summay.Contains(input.Keyword.Trim()))
                .OrderByDescending(a => a.Id)
                .Select(a => new PolicyItem
                {
                     Title = a.Title,
                      Summay = a.Summay,
                       PostDepart=a.PostDepart,
                        Statu = a.Statu,
                         Id = a.Id
                })
                .ToPagedListAsync(input.PageIndex, input.PageSize);
            return list;
        }

        /// <summary>
        /// 详细信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_List), HttpGet("/Policy/Detail"), ApiDescriptionSettings(Name = "Detail")]
        public async Task<Policy> DetailAsync([FromQuery, Required] long Id)
        {
            var info = await _policyRepository.FirstOrDefaultAsync(a => a.Id.Equals(Id));
            return info;
        }


        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_Delete), HttpPost("/Policy/Delete"), ApiDescriptionSettings(Name = "Delete")]
        public async Task DeleteRange(PolicyDeleteRangeInput input)
        {
            //await _policyRepository.Context.BatchUpdate<Policy>()
            //   .Set(b => b.IsDeleted, b => true)
            //   .Where(b => input.Ids.Contains(b.Id))
            //   .ExecuteAsync();
            await _policyRepository.Entities.Where(b => input.Ids.Contains(b.Id)).ExecuteUpdateAsync(s => s.SetProperty(b => b.IsDeleted, b => true));
        }


        /// <summary>
        /// 删除后恢复
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [SecurityDefine(ConstPermission.Policy_Recovery), HttpPost("/Policy/Recovery"), ApiDescriptionSettings(Name = "Recovery")]
        public async Task RecoveryRange(PolicyDeleteRangeInput input)
        {
            await _policyRepository.Entities.Where(b => input.Ids.Contains(b.Id)).ExecuteUpdateAsync(s => s.SetProperty(b => b.IsDeleted, b => false));
        }

    }
}
